iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
自我挑戰組

Rayeee 的 TypeScript 的學習日記系列 第 5

<20230906> Day5. 型別推論及型別註釋 Type Inference & Type Annotations 簡介一下下

  • 分享至 

  • xImage
  •  

前面提到了 TypeScript 中最重要的就是 Type system、也就是重點是型別的部分,那我們要怎麼讓 TypeScript 知道各個變量的型別 (Types) 是什麼呢?

在 TypeScript 中有兩個方法:

  • 型別推論 Type Inference
  • 型別註釋 Type Annotations

這兩個嚴格來說是 TypeScript 中兩個不同的系統,目的都是 TypeScript 中用來定義型別的方式

Type Annotations 型別註釋

就是看 TypeScript 的程式碼時,在宣告變數時那個放在變數後面的型別

型別註釋就是直接用程式碼告訴編譯器這個變量的型別。通常方式是在後面使用冒號,冒號後面加上型別

let apples: number = 5;
let no: null = null;
let un: undefined = undefined;
let now: Date = new Date();        // JavaScript Date 也是一種型別
let colors: string[] = [];        // 由 string 組成的 Array
let truths: boolean[] = [true, false];        // 由 boolean 組成的 Array

那當我們像平常一樣在寫 JavaScript,直接宣告變數不接型別時呢?

https://ithelp.ithome.com.tw/upload/images/20230906/20162544NTuyII7RBr.png

欸欸欸?為什麼明明沒有定義 Tpye,TypeScript 卻會知道他的 Type 呢?
這邊就是另一個機制 Type Inference 運作的結果

Type Inference 型別推論

型別推論就是 TypeScript 編譯器透過程式碼經由變量的初始值以及上下文,自動判斷類型。
當沒有指定是型別註釋(Type Annotations)時,就會由型別推論(Type Inference)來判斷、定義型別

類型推斷是 TypeScript 編譯器自動根據變量的初始值和上下文推斷出變量的類型的能力。當變量聲明時沒有顯式指定類型註解時,編譯器會嘗試根據變量的使用上下文來確定其類型。

欸欸,那我們怎麼不全部都給 TypeScript 判斷就好呢,還要自己給那麼麻煩

莫急莫急,之後就會講到各自適合的使用時機

但是在這之前,有關型別推論,我們可以先了解一下,建立一個變數時做了哪些事情

每當我們建立一個新變數時,我們實際上都經歷了兩個獨立的步驟:

  1. 變數宣告 Variable Deciaration
  2. 變數賦值 Variable Initialization

先宣告變數、再賦值變數

然後說到型別推論的規則

如果我們在同一行或是同一個表達式宣告及賦值,那麼 TypeScript 會依照我們要分配給該變數的值推論出 Type 為何

因為要同一行才會觸發 Type Inference,所以像這樣分成兩行就不會觸發
test01 就會變成預設的 Type any,而不是 string
也可以看成第一行宣告變數時,這時的 test01 的值會是 undefined,所以 TypeScript 這時就會 Type Inference 成 any Type 了

https://ithelp.ithome.com.tw/upload/images/20230906/20162544BxYeuoY84j.png

何時使用,該使用誰?

什麼情況下應該使用 Type Inference,以及 Type Annotations 呢?

先下結論
一般情況下,TypeScript 是建議使用 Type Inference 型別推論
(提前的註解:最終還是要看個專案的結構而定)

只有在這三種情況下我們會依賴型別註釋 Type Annotations

  1. 當有一個 function 回傳 any type,但我們需要正確的 type 的時候
  2. 當我們把變數宣告及變數賦值這兩個事情分兩行的時候
  3. 當型別推論 Type Inference 無法正確的判斷 Type 時

以下是一些情境範例:

1. 當有一個 function 回傳 any type,但我們需要正確的 type 的時候

在實作中,我們常常需要調用 JSON.parse() 解析 JSON,而這時我們通常是不會百分之百的知道解析完 JSON 之後各個參數值的型別為何
TypeScript 這時也無法預測,所以在型別推論 Type Inference 之後會給 any 型別

https://ithelp.ithome.com.tw/upload/images/20230906/20162544eqk0Ed5LwP.png

像下面的範例,經由 Type Inference 後,jsonData 會是 any 型別,這時 Type Inference 就不夠用,我們就需要 Type Annotations

https://ithelp.ithome.com.tw/upload/images/20230906/201625442uEzEqh09L.png

2. 當我們把變數宣告及變數賦值這兩個事情分兩行的時候,

變數就會被標記成 any

實作上我們常常會有這種寫法

let flag;

if (something()) {
    flag = true;
}

上面這樣,這時 TypeScript 就會把 flag 型別推論 Type Inference 成 any Type

這時就可以用 Type Annotations 型別註釋,先把型別標記好

let flag: boolean;

if (something()) {
    flag = true;
}

3. 當型別推論 Type Inference 無法正確的判斷 Type 時

有時有會有這種變數型別變來變去的專案

let arr = [9, 6. -2023];
let numberLessThanZero = false;

for (let i = 0; i < arr.length; i++) {
    if (arr[i] < 0) {
        numberLessThanZero = arr[i];
    }
}

numberLessThanZero 參數會在達成條件時,被賦值成
number,這時 TypeScript 就會報錯

叭叭!先生違規囉,讓我看一下你的型別證件 🪪

因為第 2 行時,TypeScript 已經 Type Inference 參數 numberLessThanZero 是 boolean 型別
所以偵測到它即將被賦予 number 時,就會報錯

https://ithelp.ithome.com.tw/upload/images/20230906/20162544ALqqYKJerJ.png

這時就可以使用型別註釋 Type Annotations 來手動把型別寫上去,如下

https://ithelp.ithome.com.tw/upload/images/20230906/201625447NlCE2s874.png

以上是關於型別推論及型別註釋一些簡介,以及大部分會使用 Type Annotations 的情況
明天會繼續補充有關 Type Annotations 的部分

參考資料


上一篇
<20230905> Day4. Types 有哪些呢
下一篇
<20230907> Day6. 再...再一口... 再來一口 Type Inference & Type Annotations
系列文
Rayeee 的 TypeScript 的學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言